// Keywords: recombination suppression, inversion, gamete generation, meiosis

initialize() {
	defineConstant("L", 1000000);
	defineConstant("INV_LENGTH", 500000);
	defineConstant("INV_START", asInteger(L/2 - INV_LENGTH/2));
	defineConstant("INV_END", INV_START + INV_LENGTH - 1);
	defineConstant("N", 500);
	
	initializeMutationRate(1e-7);
	initializeMutationType("m1", 0.5, "f", 0.0);  // neutral sites
	initializeMutationType("m2", 0.5, "f", 0.0);  // start marker
	initializeMutationType("m3", 0.5, "f", 0.0);  // end marker
	c(m2,m3).convertToSubstitution = T;
	c(m2,m3).color = "red";
	
	initializeGenomicElementType("g1", m1, 1.0);
	initializeGenomicElement(g1, 0, L-1);
	initializeRecombinationRate(1e-8);
}
1 late() {
	sim.addSubpop("p1", N);

	// give some genomes an inversion
	inverted = sample(p1.genomes, 100);
	inverted.addNewDrawnMutation(m2, INV_START);
	inverted.addNewDrawnMutation(m3, INV_END);
}
mutationEffect(m2) {
	// fitness of the inversion is frequency-dependent
	f = sim.mutationFrequencies(NULL, mut);
	return 1.0 - (f - 0.5) * 0.2;
}
5000 late() {
	sim.outputFixedMutations();
	
	// Assess fixation inside vs. outside the inversion
	pos = sim.substitutions.position;
	catn(sum((pos >= INV_START) & (pos < INV_END)) + " inside.");
	catn(sum((pos < INV_START) | (pos >= INV_END)) + " outside.");
}

recombination() {
	gm1 = genome1.containsMarkerMutation(m2, INV_START);
	gm2 = genome2.containsMarkerMutation(m2, INV_START);
	if (!(gm1 | gm2)) {
		// homozygote non-inverted
		return F;
	}
	inInv = (breakpoints > INV_START) & (breakpoints <= INV_END);
	if (sum(inInv) % 2 == 0) {
		return F;
	}
	if (gm1 & gm2) {
		// homozygote inverted
		left = (breakpoints == INV_START);
		right = (breakpoints == INV_END + 1);
		breakpoints = sort(c(breakpoints[!(left | right)],
			c(INV_START, INV_END + 1)[c(sum(left) == 0, sum(right) == 0)]));
		return T;
	} else {
		// heterozygote inverted: resample to get an even number of breakpoints
		// this is *recursive*: it calls this recombination callback again!
		breakpoints = sim.chromosome.drawBreakpoints(individual);
	}
	return T;
}
